package com.zenglx.multilanguage.method;


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.zenglx.multilanguage.exception.MapperException;
import com.zenglx.multilanguage.metadata.ZlxTableInfo;
import com.zenglx.multilanguage.provider.SnowflakeKeyGenerator;
import com.zenglx.multilanguage.util.Pair;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.mapping.StatementType;


/**
 * SelectList 兼容MP原生方法
 */
public class Insert extends com.baomidou.mybatisplus.core.injector.methods.Insert {
    protected String getStatementName() {
        return "测试";
    }

    protected Pair<KeyGenerator, String> processKey(
            ZlxTableInfo zlxTableInfo) {
        return new Pair<>(newSelectKeyMappedStatement(),   zlxTableInfo.getKeyColumn());
    }

    /**
     * 新建SelectKey节点
     *
     */
    @SuppressWarnings("deprecation")
    protected KeyGenerator newSelectKeyMappedStatement() {
        String keyId = getStatementName() + SelectKeyGenerator.SELECT_KEY_SUFFIX;
        if (super.configuration.hasKeyGenerator(keyId)) {
            throw new MapperException("走新注入流程的话 这种情况应该不会出现, 检查下逻辑看");
        }
        // 这是在配置中
        DefaultIdentifierGenerator defaultIdentifierGenerator = new DefaultIdentifierGenerator();
        return new SnowflakeKeyGenerator(defaultIdentifierGenerator);


    }
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        ZlxTableInfo zlxTableInfo = (ZlxTableInfo)tableInfo;
        if(zlxTableInfo.isMultiLanguage()) {
            KeyGenerator keyGenerator = NoKeyGenerator.INSTANCE;
            SqlMethod sqlMethod = SqlMethod.INSERT_ONE;
            String columnScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlColumnMaybeIf(null),
                    LEFT_BRACKET, RIGHT_BRACKET, null, COMMA);
            String valuesScript = SqlScriptUtils.convertTrim(tableInfo.getAllInsertSqlPropertyMaybeIf(null),
                    LEFT_BRACKET, RIGHT_BRACKET, null, COMMA);
            String keyProperty = null;
            String keyColumn = null;
            // 表包含主键处理逻辑,如果不包含主键当普通字段处理
            if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) {
                if (tableInfo.getIdType() == IdType.AUTO) {
                    /* 自增主键 */
                    keyGenerator = Jdbc3KeyGenerator.INSTANCE;
                    keyProperty = tableInfo.getKeyProperty();
                    keyColumn = tableInfo.getKeyColumn();
                    String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
                    SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
                    return this.addInsertMappedStatement(mapperClass, modelClass, getMethod(sqlMethod), sqlSource, keyGenerator, keyProperty, keyColumn);
                }
            }
            String id = getMethod(sqlMethod);
            //先处理cache或bind节点
            Pair<KeyGenerator, String> keyGeneratorKeyColumnPair = processKey(zlxTableInfo);
            String statementName = mapperClass.getName() + DOT + id;
            boolean flat = configuration.hasStatement(statementName, false);
            if (flat) {
                logger.warn(LEFT_SQ_BRACKET + statementName + "] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [" + getClass() + RIGHT_SQ_BRACKET);
                return null;
            }
            String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);
            SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
            return builderAssistant.addMappedStatement(id, sqlSource, StatementType.PREPARED, SqlCommandType.INSERT,
                    null, null, null, modelClass, null, Integer.class,
                    null, true, false, false,keyGeneratorKeyColumnPair != null ? keyGeneratorKeyColumnPair.getFirst() : null,
                    keyGeneratorKeyColumnPair != null ? keyGeneratorKeyColumnPair.getSecond() : null,
                    keyGeneratorKeyColumnPair != null ? keyGeneratorKeyColumnPair.getSecond() : null,
                    configuration.getDatabaseId(), languageDriver, null);
        } else {
            return super.injectMappedStatement(mapperClass, modelClass, tableInfo);
        }
    }

}
